package com.xb.loan.fund.impl;

import com.palm.plat.account.service.ICashService;
import com.palm.plat.account.service.constant.AccountConst;
import com.palm.plat.framework.exception.BizException;
import com.palm.plat.fund.common.VerifySet;
import com.palm.plat.fund.dao.CashTransferDao;
import com.palm.plat.fund.dao.bean.CashTransfer;
import com.palm.plat.fund.dao.bean.StatUserTransfer;
import com.palm.plat.fund.dao.bean.TotalMoneyAndNum;
import com.palm.plat.fund.service.ICashTransferService;
import com.palm.plat.fund.service.bean.CashTransferVO;
import com.palm.plat.fund.service.bean.StatUserTransferVO;
import com.palm.plat.fund.service.bean.TotalMoneyAndNumVO;
import com.palm.plat.fund.service.constant.FundConst;
import com.palm.plat.fund.service.exception.IFundServiceException;
import com.palm.plat.usercenter.partner.service.IPartnerInfoService;
import com.palm.plat.usercenter.partner.service.bean.PartnerInfoVO;
import com.palm.plat.usercenter.user.service.IUserService;
import com.palm.plat.usercenter.user.service.bean.UserInfoVO;
import com.palm.plat.util.cache.redis.comm.FormatOperation;
import com.palm.plat.util.common.SpringHelper;
import com.palm.plat.util.common.StringUtils;
import com.palm.plat.util.common.common.ObjectOperation;
import com.palm.plat.util.common.log.DefaultLoggerFacotry;
import com.palm.plat.util.common.log.LogFormatUtil;
import com.palm.plat.util.mybatis.MyTransactional;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 北京掌中彩信息科技有限公司源代码，版权归北京掌中彩信息科技有限公司所有。
 * 
 * 项目名称 : common-biz 
 * 创建日期 : 2015年9月7日 
 * 修改历史 : 
 * 1. [2015年9月7日]创建文件 by wenju.song
 */
@Service("cashTransferService")
public class CashTransferServiceImpl implements ICashTransferService {
	private static Logger logger = DefaultLoggerFacotry.getLogger(CashTransferServiceImpl.class);
	
	@Autowired
	private IUserService userService;

	@Autowired
	private CashTransferDao cashTransferDao;

	@Autowired
	private ICashService cashService;
	
	@Autowired
	private IPartnerInfoService partnerInfoService;
	
	@Override
	public String transferCash(CashTransferVO cashTransferVO) throws BizException {
		CashTransferVO cashTransferVODB = queryCashTransferByPid(cashTransferVO.getPartnerId(), cashTransferVO.getPid());
		//重复订单
		if(cashTransferVODB != null){
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "partnerId", "porderId", "msg"},
					new Object[]{"transfer", cashTransferVO.getPartnerId(), cashTransferVO.getPid(),
					IFundServiceException.RepeatOrder.getMessage()}));
			throw IFundServiceException.RepeatOrder;
		}
		
		PartnerInfoVO partnerInfoVO = partnerInfoService.selectByPrimaryKey(cashTransferVO.getPartnerId());
		UserInfoVO sponsorUserInfoVO = userService.queryUserInfoById(partnerInfoVO.getPayUserid());
		UserInfoVO followUserInfoVO = userService.queryUserInfoById(cashTransferVO.getFollowUserId());
		// 验证用户是否处于正常状态
		VerifySet.verifyUserInfoVOIsNormal(sponsorUserInfoVO);
		VerifySet.verifyUserInfoVOIsNormal(followUserInfoVO);
		// 验证转出用户是否属于该渠道
		VerifySet.verifyUserRelation2Partner(followUserInfoVO, cashTransferVO.getPartnerId(), partnerInfoService, "transfer");

		CashTransfer cashTransfer = (CashTransfer) ObjectOperation.convertByClasses(cashTransferVO, CashTransfer.class);
		String transferId = FormatOperation.assemblySeq(FundConst.PriKey_Name, FundConst.PriKey_Length);
		cashTransfer.setTransferId(transferId);
		if(StringUtils.isEmpty(cashTransfer.getPid()))
		    cashTransfer.setPid(transferId);
		cashTransfer.setSponsorUserId(sponsorUserInfoVO.getUserId());
		cashTransfer.setSponsorAccountId(sponsorUserInfoVO.getAccountId());
		cashTransfer.setFollowAccountId(followUserInfoVO.getAccountId());
		cashTransfer.setCreateTime(FormatOperation.formatDateToYMDHms14(new Date()));
		
		//转账事务
		CashTransferServiceImpl self = SpringHelper.getBean("cashTransferService");
		self.transferCashTransaction(cashTransfer, sponsorUserInfoVO, followUserInfoVO);
		return transferId;
	}

	@MyTransactional
	public void transferCashTransaction(CashTransfer cashTransfer, UserInfoVO sponsorUserInfoVO, 
			UserInfoVO followUserInfoVO) throws BizException {
		
		if (cashTransfer.getTransferType() == FundConst.TransferType_ProxyCharge){
			// 代充值，扣渠道钱，为用户加钱
			cashService.transfer(cashTransfer.getTransferId(), sponsorUserInfoVO, followUserInfoVO, 
					cashTransfer.getMoney(), AccountConst.BillType_Proxy_Charge_Out, 
					AccountConst.BillType_Proxy_Charge_In, null);
		}else if (cashTransfer.getTransferType() == FundConst.TransferType_ProxyEncash){
			// 代提现，扣用户钱，为渠道加钱
			cashService.transfer(cashTransfer.getTransferId(), followUserInfoVO, sponsorUserInfoVO, 
					cashTransfer.getMoney(), AccountConst.BillType_Proxy_Encash_Out, 
					AccountConst.BillType_Proxy_Encash_In, null);
		}else{
			logger.error(LogFormatUtil.getFormatMsg(new String[]{"module", "transferType", "msg"},
					new Object[]{"cash-transfer", cashTransfer.getTransferType(),
					IFundServiceException.invalidTransferType.getMessage()}));
			throw IFundServiceException.invalidTransferType;
		}
		
		// 设置业务订单状态，扣费失败的订单走不到此处，不会留有失败订单记录
		cashTransfer.setStatus(FundConst.TransferStatus_Success);
		// 插入订单
		cashTransferDao.insert(cashTransfer);
	}
	
	@Override
	public CashTransferVO queryCashTransferById(String transferId) throws BizException {
		CashTransfer cashTransfer = cashTransferDao.queryCashTransferById(transferId);
		if(cashTransfer != null)
            cashTransfer.setCreateTime(FormatOperation.formatYMDHms14ToY_M_DHms(cashTransfer.getCreateTime()));
		return ObjectOperation.convertByClasses(cashTransfer, CashTransferVO.class);
	}

	@Override
	public CashTransferVO queryCashTransferByPid(String partnerId, String pid) throws BizException {
		CashTransfer param = new CashTransfer();
		param.setPartnerId(partnerId);
		if(StringUtils.isEmpty(pid))
		    pid = "";
		param.setPid(pid);
		CashTransfer cashTransfer = cashTransferDao.queryCashTransferByPid(param);
		if(cashTransfer != null)
		    cashTransfer.setCreateTime(FormatOperation.formatYMDHms14ToY_M_DHms(cashTransfer.getCreateTime()));
		return ObjectOperation.convertByClasses(cashTransfer, CashTransferVO.class);
	}

	@Override
	public List<CashTransferVO> queryCashTransfer(String userId, String partnerId, Integer transferType, String startDate, String endDate, int pageNum, int numPerPage) throws BizException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("userId", userId);
		params.put("partnerId", partnerId);
		params.put("transferType", transferType);
		params.put("startDate", FormatOperation.formatY_M_DHmsToYMDHms14(startDate));
		params.put("endDate", FormatOperation.formatY_M_DHmsToYMDHms14(endDate));
		params.put("pageNum", pageNum);
		params.put("numPerPage", numPerPage);
		
		List<CashTransfer> cashTransferList = cashTransferDao.queryCashTransfer(params);
		if (cashTransferList != null){
		    for(CashTransfer cashTransfer : cashTransferList)
		        cashTransfer.setCreateTime(FormatOperation.formatYMDHms14ToY_M_DHms(cashTransfer.getCreateTime()));
		}
		return ObjectOperation.convertByClassesList(cashTransferList, CashTransferVO.class);
	}

	@Override
	public int queryCashTransferCount(String userId, String partnerId, Integer transferType, String startDate, String endDate) throws BizException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("userId", userId);
		params.put("partnerId", partnerId);
		params.put("transferType", transferType);
		params.put("startDate", FormatOperation.formatY_M_DHmsToYMDHms14(startDate));
        params.put("endDate", FormatOperation.formatY_M_DHmsToYMDHms14(endDate));
		return cashTransferDao.queryCashTransferCount(params);
	}

//	@Override
	public TotalMoneyAndNumVO queryTotalMoneyAndNum(String userId, String partnerId, Integer transferType, String startDate, String endDate) throws BizException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("userId", userId);
		params.put("partnerId", partnerId);
		params.put("transferType", transferType);
		params.put("startDate", startDate);
		params.put("endDate", endDate);
		
		TotalMoneyAndNum totalMoneyAndNum = cashTransferDao.queryTotalMoneyAndNum(params);
		if(totalMoneyAndNum == null)
			return null;
		
		return ObjectOperation.convertByClasses(totalMoneyAndNum, TotalMoneyAndNumVO.class);
	}

	@Override
	public List<StatUserTransferVO> queryStatUserTransfer(String statTime) {
		
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("statTime", statTime);
		List<StatUserTransfer> stfList = cashTransferDao.queryStatUserTransfer(params);
		return ObjectOperation.convertByClassesList(stfList, StatUserTransferVO.class);
	}

}
